<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    // 所谓的 递归 就是 函数自己调用自己或间接调用自己
    /*
    function func1 () {
        func1();
    } // 直接调用自己

    function func2() {
        func3();
    }
    function func3() {
        func2();
    } // 间接调用
    */


    // 递归其实就是 将一个 未知的问题转换成一个已经解决的问题来计算( 划归 )
    // 1, 等差数列
    // 1, 3, 5, 7, 9, ... 
    // 通项公式: f = 2 * n + 1

    // 用递归如何计算 第 n 项的值
    // 1> 先假定这个功能已经实现, 记为 function func( n ) { ??? }
    // 2> 检查 第 n 项 与 第 n-1 等项之间的关系( 表达式 ): func( n ) => func( n-1 ) + 2
    // 3> 检查临界条件, 什么时候跳出( 根据条件看 第 0 项 的时候 是 1, 第 1 项 3, ... )

    function func( n ) {

        // 临界
        if( n == 0 ) return 1;
        // if ( n == 1 ) return 3;
        
        return func( n-1 ) + 2; // 地推关系, 划归
        // 思想: 我们原本要计算的是 第 n 项, 但是假定已经实现, 因此可以将其转换成计算 第 n-1 项
    }

    for( var i = 0; i < 20; i++ ) {
        console.log( '通项公式: f( ' + i + ' ) = ' + ( i * 2 + 1 ) + ', 递归计算: func( ' + i + ' ) = ' + func( i ) );
    }


    // 递归的练习
    // 1> 差分等差数列
    //      1, 2, 4, 7, 11, 16, ...
    // 2> 求 幂
    //      pow( a, b ): a 的 b 次方
    //      Math.pow( ... )
    // 3> 求阶乘
    //      5! => 5 * 4 * 3 * 2 * 1
    //      n! => n * ( n - 1 ) * ( n - 2 ) * ... * 1
    // 4> Fibonacci 数列
    //      1, 1, 2, 3, 5, 8, 13, ...
    
</script>
</html>